package com.cu.jiekong.service;

import com.alibaba.fastjson.JSON;
import com.cu.jiekong.constants.BizConstants;
import com.cu.jiekong.constants.ResultStatus;
import com.cu.jiekong.dao.UserLoggingSessionMapper;
import com.cu.jiekong.dao.UserMapper;
import com.cu.jiekong.frame.CacheManager;
import com.cu.jiekong.frame.exception.BizException;
import com.cu.jiekong.frame.model.Ret;
import com.cu.jiekong.model.User;
import com.cu.jiekong.model.UserLoggingSession;
import com.cu.jiekong.util.StringUtil;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.util.Date;

/**
 * @author jintian
 * @date 13:40
 */
@Service
public class UserService {

    private Logger logger = LoggerFactory.getLogger(UserService.class);

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private UserLoggingSessionMapper sessionMapper;

    @Autowired
    private CacheManager cacheManager;

    /**
     * 用户登录
     *
     * @param request 请求
     * @param user    请求登录用户
     * @return
     */
    @Transactional
    public Ret login(HttpServletRequest request, User user) {
        logger.info("login user " + JSON.toJSONString(user));
        // 查询到的用户信息
        User queryedUser = userMapper.queryByUserName(user.getUserName());
        if (queryedUser == null) {
            logger.info("user is not exit");
            return new Ret("000001", "用户不存在，请检查后再登录");
        }
        Date overDate = checkErrorTime(queryedUser.getErrorNum(), queryedUser.getErrorTime());
        if (new Date().before(overDate)) {
            return new Ret("000001", "用户登录过于频繁，请稍后再试！", overDate);
        }
        // 检查用户名密码
        if (!StringUtil.MD5(user.getUserPassward()).equals(queryedUser.getUserPassward())) {
            userMapper.addErrorTime(queryedUser.getId());
            return new Ret("000001", "用户登录密码错误");
        } else {
            // 重置连续登陆错误次数
            userMapper.removeErrorTime(queryedUser.getId());
            String sessionId = StringUtil.UUIDStr();

            // 将session放到数据库或者redis中
            UserLoggingSession userLoggingSession = new UserLoggingSession(queryedUser.getId(), sessionId);
            if (sessionMapper.updateByPrimaryKey(userLoggingSession) < 1) {
                sessionMapper.insert(userLoggingSession);
            }

            // redis 存入sessionId
            cacheManager.setValue(BizConstants.LOGIN_SESSION_HEAD + sessionId, user.getId());

            HttpSession session = request.getSession();
            // 生成唯一编码给放到session中
            session.setAttribute("sessionId", sessionId);
            return new Ret("000000", "登录成功");
        }
    }


    /**
     * 检查用户登录是否在连续错误数范围时间内
     *
     * @param errorNum
     * @param errorTime
     * @return
     */
    private Date checkErrorTime(int errorNum, Date errorTime) {
        if (errorNum <= 3) {
            return errorTime;
        }
        long overTime = (long) ((30 * Math.pow(2, errorNum - 3)) / 1);
        return new Date(errorTime.getTime() + overTime);
    }

    /**
     * 登出
     *
     * @param userId
     * @return
     */
    public Ret loginOut(int userId, HttpServletRequest request) {
        // 清除session 表中记录
        sessionMapper.deleteByPrimaryKey(userId);

        // 清楚redis中session 记录
        cacheManager.deleteKey(BizConstants.LOGIN_SESSION_HEAD + request.getSession().getAttribute("sessionId").toString());
        return new Ret("000000", "seccess");
    }

    /**
     * 检查用户是否登录
     *
     * @param sessionId
     * @return
     */
    public Ret chechLogin(String sessionId) {
        // TODO
        return new Ret(ResultStatus.RESULT_000000.getCode(), ResultStatus.RESULT_000000.getMsg());
    }

    /**
     * @param userId 用户id
     * @param sign
     * @return
     */
    public User getUserByUserId(String userId, String sign) throws BizException{
        if (!StringUtil.MD5(userId).equals(sign)) {
            throw new BizException(ResultStatus.RESULT_400001.getCode(), ResultStatus.RESULT_400001.getMsg());
        }
        return userMapper.selectByPrimaryKey(Integer.valueOf(userId));
    }

   /* @Override
    public UserDetails loadUserByUsername(String s) throws UsernameNotFoundException {
        User user = userMapper.queryByUserName(s);
        if (user == null) {
            throw new UsernameNotFoundException("name:" + s);
        }
        UserSecurity userSecurity = new UserSecurity(user.getUserName(), user.getUserPassward());
        return userSecurity;
    }*/
}
